Conversation
|
Very interesting, I had no idea that lld could link MinGW and MSVC objects together. This links against |
|
Mingw isn't used at all with this patch. Everything uses Visual Studio.
Locally, I even manage to run I also have a patch for Static PHP CLI, but it's not working because the PHP source code and Makefile on Windows doesn't support building a static version of |
That's the part I was missing, thank you! |
|
Gave it a shot and updated your initial post for instructions, however, once it attempts to serve a php file with |
|
Have you copied all the necessary DDLs in the same directory? |
|
Shouldn't be necessary with $env:PATH += ";$env:VCPKG_ROOT\installed\x64-windows\bin"
$env:PATH += ";C:\watcher-x86_64-pc-windows-msvc"
$env:PATH += ";C:\php-8.5.1-Win32-vs17-x64"Is anything else required? |
|
You must also add |
|
Same issue, I don't think it could be related to libraries anyway, as it would fail to run in the first place then. Shared libraries are (by default) loaded at initialisation time and we're not passing delayload arguments to the compilation. Log: ❯❯ frankenphp git:(windows) 21:46 .\frankenphp.exe php-server --root=./
2026/01/10 20:46:22.912 WARN admin admin endpoint disabled
2026/01/10 20:46:22.912 INFO tls.cache.maintenance started background certificate maintenance {"cache": "0x2e61d3850500"}
2026/01/10 20:46:22.912 WARN http.auto_https server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server {"server_name": "php", "http_port": 80}
2026/01/10 20:46:22.949 INFO frankenphp FrankenPHP started 🐘 {"php_version": "8.5.1", "num_threads": 64, "max_threads": 64}
2026/01/10 20:46:22.950 WARN http HTTP/2 skipped because it requires TLS {"network": "tcp", "addr": ":80"}
2026/01/10 20:46:22.950 WARN http HTTP/3 skipped because it requires TLS {"network": "tcp", "addr": ":80"}
2026/01/10 20:46:22.950 INFO http.log server running {"name": "php", "protocols": ["h1", "h2", "h3"]}
2026/01/10 20:46:22.951 INFO Caddy serving PHP app on :80
2026/01/10 20:46:22.953 INFO tls storage cleaning happened too recently; skipping for now {"storage": "FileStorage:C:\\Users\\m\\AppData\\Roaming\\Caddy", "instance": "489ade52-21ab-40c6-b18a-2932fb8eab4d", "try_again": "2026/01/11 20:46:22.953", "try_again_in": 86400}
2026/01/10 20:46:22.953 INFO tls finished cleaning storage units
❯❯ frankenphp git:(windows) 21:46Text files like an index.html page are served just fine. Only when php is attempted to be executed does the program simply stop. |
|
I didn't try the |
|
Could you also show me the content of your PHP script? |
|
Content of the php script: <?php
echo phpinfo();I haven't ran the test suite yet, but |
|
Here is a build I created locally: https://drive.google.com/file/d/1B09de1rERpRUN-bnAje0K2vHcwhVoDJa/view?usp=sharing On my computer, it runs Symfony without issue @henderkes. |
|
Thanks, I'll try this one and report back. Edit: it's working, but it was linked against 8.5.3-dev. I'll try to link against 8.5.1 again and see if I can get anywhere after the new commits. |
|
@dunglas I've prepared everything except for the failing tests. We cannot switch to watcher-c from vcpkg because they included the header-only c++ version, so it's not usable for us. |
|
Thank you vert much! What tests are failing? The CI looks green. |
|
You set the windows workflow to upload first and run tests later (ignoring errors), so the CI looks green but the go test run is failing: https://github.com/php/frankenphp/actions/runs/22378079619/job/64772633591 It's only the extension generator tests though, the rest is OK. |
|
This should be good to merge then? 🥳 |
|
This is a huge milestone!! Thank you to everyone involved, especially you, @TenHian, and @henderkes. |
|
Any chance to get a build before official one? I'm so excited about that! |
|
https://github.com/php/frankenphp/actions/runs/22440426838/job/64981105036 Our CI uploads binaries. Though it's obviously not meant for production use as it doesn't have version variables & co set. |
|
I played around with CI uploads binaries. All works with Laravel. Great achievement! |
|
I played with it too, it is as "slow" as Caddy + php-cgi.exe on my side. |
|
I would be surprised if it was much faster in latency, though throughput should be better. If it isn't, I'll take a look. The inherent issue with php in windows is that php runs very poorly on windows in general. Many optimisations are done specifically for unix or even gnu-linux, for typical linux compilers gcc (and only now clang, without preserve_none support on windows) and then, even worse, the windows file system and intrusive file scanning make it extremely slow to open files, which php does a lot. A composer install takes 10x longer on the first run on windows compared to in WSL. That's a difference no webserver can "fix". The only "fix" for it is using a system suitable for php, which windows simply isn't. |
|
So I've played around with it with the symfony/demo repository. First, response times of ~800ms, after disabling Antivirus it's 250-400ms. With worker mode it's 120ms. I'll set up mirrored wsl mode and play with wrk a bit. |
|
Results look about as I expected. FrankenPHP is much faster than untuned Apache. Of course it's still awfully slow, it's Windows after all, but that's not something we can fix. This is with Antivirus disabled, with it enabled multiply the results by 2. It's bad. XAMPP (updated to php 8.5, default configuration): FrankenPHP (php-server): FrankenPHP (php-server) worker mode: And for fun, FrankenPHP on Linux: Tl;dr: just don't use Windows. Don't do it to yourself. |
|
Thanks for the benchs! Is yiur linux benchmark on WSL? |
|
Yeah on WSL, same machine. |
|
I also want to run a benchmark against frankenphp windows-binary vs. ubuntu-24.04 - wsl. Any hints on this:
Thank you. |
No, definitely not. The first iteration of WSL was beyond broken. Use a real VM instead. |

Closes #83 #880 #1286.
Working patch for Windows support.
Supports linking to the official PHP release (TS version).
Includes some work from #1286 (thanks @TenHian!!)
This patch allows using Visual Studio to compile the cgo code. To do so, it must be compiled with Go 1.26 (RC) with the following setup:
TODO: